<template>
  <el-row class="calendar-wrap">
    <el-col
      :xs="24"
      :md="5"
      :class="[
        'left-wrap',
        device === 'mobile' ? '' : 'height-100'
      ]"
    >
      <section class="mb-12">
        <el-divider content-position="left">
          说明
        </el-divider>
        <h3 class="mb-12">
          官方文档：
        </h3>
        <el-link
          href="https://fullcalendar.io/docs"
          type="primary"
          target="_blank"
          class="mb-12"
        >
          FullCalendar 官方文档
        </el-link>

        <h3 class="mb-12">
          常见用途：
        </h3>
        <ul class="mb-12">
          <li class="mb-12">
            1. 设置定时任务可使用日期视图模式
          </li>
          <li>2. 添加日程、约定会议室等可以使用日期视图模式</li>
        </ul>

        <h3 class="mb-12">
          备注：
        </h3>
        <ul>
          <li class="mb-12">
            1. 如果需求中有加农历、24节气和中国节假日的功能，请移步
            <el-link
              href="https://github.com/hjdev/vue-lunar-fullcalendar"
              type="primary"
              target="_blank"
            >
              vue-lunar-full-calendar
            </el-link>
          </li>

          <li>
            2.
            <el-link
              href="https://hjdev.github.io/vue-lunar-fullcalendar/#/vue-lunar-fullCalendar"
              type="primary"
              target="_blank"
            >
              vue-lunar-full-calendar 离线Demo示例
            </el-link>
          </li>
        </ul>
      </section>
      <el-divider />
      <section class="options-wrap mb-12">
        <el-button
          v-if="editable === true"
          v-blur
          type="primary"
          @click="handleEditableComplete"
        >
          配置完成
        </el-button>
        <el-button
          v-else
          v-blur
          type="primary"
          @click="handleSetEditable"
        >
          开始配置
        </el-button>
      </section>
      <ul>
        <li
          v-for="item of configurations"
          :key="item.id"
          :class="[
            'configuration-item',
            editable ? 'editable' : ''
          ]"
        >
          <p class="configuration-item__label">
            {{ item.label }}
          </p>
          <p class="configuration-item__options">
            <el-button
              v-blur
              type="primary"
              link
              @click="showTaskInfo(item)"
            >
              查看
            </el-button>
            <el-button
              v-blur
              type="primary"
              link
              @click="handleSetTask(item)"
            >
              设定
            </el-button>
          </p>
        </li>
      </ul>
    </el-col>
    <el-col
      :xs="24"
      :md="19"
      :class="[
        'right-wrap',
        device === 'mobile' ? 'mt-12' : 'ml-12'
      ]"
    >
      <full-calendar
        ref="fullCalendar"
        :options="calendarOptions"
        class="demo-app-calendar"
      />
    </el-col>
  </el-row>
</template>

<script lang="ts">
import { defineComponent, ref, computed } from 'vue';

import '@fullcalendar/core/vdom';
import zhCnLocale from '@fullcalendar/core/locales/zh-cn';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';
import timeGridPlugin from '@fullcalendar/timegrid';
import FullCalendar, { EventApi } from '@fullcalendar/vue3';
import { ElMessageBox, ElMessage } from 'hive-plus';

import type { DateSelectArg, EventClickArg } from '@fullcalendar/vue3';

import { useAppStore } from '@/store/app';
import { getAllDateCN, formatDate } from '@/utils/index';

  type TaskItem = {
    id: number,
    label: string,
    value: number,
  }

export default defineComponent({
  name: 'CalendarIndex',
  components: {
    FullCalendar,
  },
  setup() {
    const appStore = useAppStore();
    const device = computed(() => appStore.device);
    const fullCalendar = ref();
    const selectDateInfo = ref <TypeObject>({});
    const configurations:TaskItem[] = [
      {
        id: 1,
        label: '制冷剂',
        value: 1,
      },
      {
        id: 2,
        label: '过渡季',
        value: 2,
      },
      {
        id: 3,
        label: '初始化模式分组',
        value: 3,
      },
      {
        id: 4,
        label: '系统初始化模式',
        value: 4,
      }
    ];
    const editable = ref(false); // 编辑配置状态，默认不可编辑

    const handleDateSelect = (selectInfo: DateSelectArg) => {
      console.log('用户选中日期范围：', selectInfo);
      selectDateInfo.value = { ...selectInfo };
    };
    const handleDateClick = (clickInfo: TypeObject) => {
      console.log('用户点击到了某一个日期上：', clickInfo);
    };
    const handleEventClick = (clickInfo: EventClickArg) => {
      ElMessageBox.confirm(
        `${JSON.stringify(clickInfo.event)}`,
        '详情',
        {
          showConfirmButton: editable.value,
          confirmButtonText: '删除',
          cancelButtonText: '关闭',
        }
      ).then(() => {
        if (!editable.value) { return; }
        clickInfo.event.remove();
        ElMessage.success('删除成功');
      }).catch(() => {
        console.log('用户点击取消删除');
      });
    };
    const handleEventsSet = (events: EventApi[]) => {
      console.log('设置日程事件：', events);
    };
    const handleEventMouseEnter = (eventInfo: TypeObject) => {
      console.log('鼠标移入日程事件：', eventInfo);
    };

    const calendarOptions = ref({
      plugins: [
        dayGridPlugin,
        timeGridPlugin,
        interactionPlugin
      ],
      initialDate: new Date(),
      initialView: 'dayGridMonth', // 初始化插件显示
      locale: zhCnLocale,
      firstDay: 0,

      // 文本将显示在headerToolbar / footerToolbar的按钮上。不支持HTML注入。所有特殊字符将被转义。
      buttonText: {
        today: '今天',
        month: '月',
        week: '周',
        day: '天',
      },
      /**
         * 在日历顶部定义按钮和标题。
         * 将headerToolbar选项设置为false不会显示任何标题工具栏。
         * 可以为对象提供属性start/center/end或left/center/right。
         * 这些属性包含带有逗号/空格分隔值的字符串。
         * 用逗号分隔的值将相邻显示。
         * 用空格分隔的值之间会显示一个很小的间隙。
         *
         */
      headerToolbar: {
        right: 'today prev,next',
        center: 'title',
        left: 'dayGridMonth,dayGridWeek,dayGridDay',
      },
      // headerToolbar: false, // 设置隐藏header

      droppable: false,
      editable: false,
      selectable: false,
      select: handleDateSelect,
      dateClick: handleDateClick,
      // selectMirror: true,
      dayMaxEvents: true,
      weekends: true, // 是否显示一周七天

      timeZone: 'local', // 采用时区
      events: [
        {
          title: '放学到校门口等我',
          date: formatDate(Date.now() - 86400000 * 2, 'YYYY-MM-DD'),
          editable: false,
          classNames: ['event-wrap'],
        },
        {
          title: '放学别跑',
          date: formatDate(Date.now(), 'YYYY-MM-DD'),
          editable: false,
          classNames: ['event-wrap'],
        },
        {
          title: '一起去打羽毛球',
          date: formatDate(Date.now() + 86400000 * 2, 'YYYY-MM-DD'),
          editable: false,
          classNames: ['event-wrap'],
        }
      ],
      eventClick: handleEventClick, // 日程点击事件
      eventMouseEnter: handleEventMouseEnter, // 用户将鼠标悬停在事件上时触发
      eventsSet: handleEventsSet,
    });

    return {
      device,
      fullCalendar,
      calendarOptions,
      configurations,
      editable,
      handleSetEditable() {
        editable.value = true;
        calendarOptions.value.editable = true;
        calendarOptions.value.selectable = true;
        calendarOptions.value.droppable = true;
      },
      handleEditableComplete() {
        editable.value = false;
        calendarOptions.value.editable = false;
        calendarOptions.value.selectable = false;
        calendarOptions.value.droppable = false;
      },
      showTaskInfo(raw:TaskItem) {
        ElMessageBox.alert(`${JSON.stringify(raw)}`, '详情', {
          confirmButtonText: '关闭',
        });
      },
      handleSetTask(raw:TaskItem) {
        const calendar = selectDateInfo.value.view.calendar;

        const dateList:string[] = getAllDateCN(selectDateInfo.value.start, selectDateInfo.value.end);
        if (dateList.length > 0) {
          dateList.length -= 1;
        }
        const newDateList = dateList.map((date) => date.split(' ')[0]);

        if (raw.label) {
          newDateList.forEach((date) => {
            calendar.addEvent({
              title: raw.label,
              start: date,
              end: date,
              allDay: true,
              editable: false, // 设置日程是否可拖拽、可编辑等
              classNames: ['event-wrap'],
            });
          });
        }
      },
    };
  },
});
</script>

<style lang="scss" scoped>
:deep(.fc-day-sun),
:deep(.fc-day-sat) {
  background-color: #fbfbfb;
}

:deep(.fc-header-toolbar) {
  margin-bottom: 12px !important;
}

:deep(.fc-col-header-cell) {
  line-height: 32px;
  color: #323232;
  background-color: #f5f5f5;
}

:deep(.fc-daygrid-day-top) {
  display: flex;
  flex-direction: row;
}

:deep(.fc-highlight) {
  background-color: #dde7fc;
  opacity: 0.7;
}

:deep(.event-wrap) {
  margin-right: 4px !important;
  margin-left: 16px !important;
  cursor: pointer !important;

  .fc-event-title-container {
    position: relative;
    box-sizing: border-box;
    padding-right: 4px;
    padding-left: 4px;
    line-height: 20px;

    &::before {
      position: absolute;
      top: 50%;
      left: -12px;
      width: 8px;
      height: 8px;
      margin-top: -4px;
      content: '';
      background-color: var(--#{$namespace}-color-primary);
      border-radius: 50%;
    }
  }
}

:deep(.fc-button) {
  display: inline-flex;
}

.mb-12 {
  margin-bottom: 12px;
}

.calendar-wrap {
  position: absolute;
  top: 0;
  left: 0;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding: 0 var(--#{$namespace}-main-padding) var(--#{$namespace}-main-padding);
  overflow-y: auto;

  .left-wrap {
    box-sizing: border-box;
    padding: 12px;
    overflow-y: auto;
    background-color: var(--#{$namespace}-color-white);

    &.height-100 {
      height: 100%;
    }

    .configuration-item {
      position: relative;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding-right: 10px;
      padding-left: 20px;
      margin-bottom: 12px;
      border: 1px solid var(--#{$namespace}-color-white);
      border-radius: 4px;

      &.editable {
        cursor: move;
        border: 1px solid var(--maia-color-grey-base);
      }

      &::before {
        position: absolute;
        top: 50%;
        left: 4px;
        width: 8px;
        height: 8px;
        margin-top: -4px;
        content: '';
        background-color: var(--#{$namespace}-color-primary);
        border-radius: 50%;
      }

      .configuration-item__label {
        display: -webkit-box;
        flex: 1;
        overflow: hidden;
        line-height: 30px;
        text-overflow: ellipsis;
        -webkit-line-clamp: 1;
        -webkit-box-orient: vertical;
      }

      .configuration-item__options {
        flex: none;
      }
    }
  }

  .right-wrap {
    box-sizing: border-box;
    flex: 1;
    height: 100%;
    padding: 12px;
    background-color: var(--#{$namespace}-color-white);

    &.ml-12 {
      margin-left: 12px;
    }

    &.mt-12 {
      margin-top: 12px;
    }

    .demo-app-calendar {
      height: 100%;
    }
  }
}
</style>
